//canvas stuff
const mainCanvas = document.getElementById('mainCanvas');
const context =  mainCanvas.getContext('2d');
context.font = '25px Arial';


//gamestate stuff
const gameStates = {
	START: 'start',
	MEMORIZE: 'memorize',
	REMEMBER: 'remember',
	END: 'end'
}

function Game(numberOfShapes, gameHeight, gameWidth, firstSceneKeybind, secondSceneKeybind, thirdSceneKeybind, fourthSceneKeybind, centerKeybind) {
	this.state = gameStates.START;
	this.scenes = [];
	for(let i = 0; i < 4; i++) {
		this.scenes[i] = new Scene(numberOfShapes, gameWidth, gameHeight);
	}
	this.rememberScenes = [];
	for(let i = 0; i < 4; i++) {
		this.rememberScenes[i] = scrambleScene(this.scenes[i]);
	}
	this.sceneIndex = 0;
	this.firstSceneKeybind = firstSceneKeybind;
	this.secondSceneKeybind = secondSceneKeybind;
	this.thirdSceneKeybind = thirdSceneKeybind;
	this.fourthSceneKeybind = fourthSceneKeybind;
	this.centerKeybind = centerKeybind;
	this.isDragging = false;
	this.offsetX = mainCanvas.getBoundingClientRect().left;
	this.offsetY = mainCanvas.getBoundingClientRect().top;
	this.startX;
	this.startY;
	this.mouseX;
	this.mouseY;
	this.selectedShapeIndex = 5;
}


//event handlers
function handleMouseMove(e) {
	if(currentGame.state !== gameStates.REMEMBER) { return; }
	if(!currentGame.isDragging) { return; }
	if(currentGame.selectedShapeIndex == 5) { return; }
	//stops browser from handing the event for us
	e.preventDefault();
	e.stopPropagation();
	//get mouse position
	currentGame.mouseX = parseInt(e.clientX - currentGame.offsetX);
	currentGame.mouseY = parseInt(e.clientX - currentGame.offsetY);
	currentGame.scenes[currentGame.sceneIndex].shapes[currentGame.selectedShapeIndex].x += currentGame.mouseX - currentGame.startX
	currentGame.scenes[currentGame.sceneIndex].shapes[currentGame.selectedShapeIndex].y += currentGame.mouseY - currentGame.startY
	renderScene(currentGame.scenes[currentGame.sceneIndex]);
}

function handleKeyboardInput(e) {
	if(currentGame.state !== gameStates.END) {
		switch (e.key) {
			case currentGame.firstSceneKeybind:
				currentGame.sceneIndex = 0;
				e.preventDefault(e);
				break;
			case currentGame.secondSceneKeybind:
				currentGame.sceneIndex = 1;
				e.preventDefault(e);
				break;
			case currentGame.thirdSceneKeybind:
				currentGame.sceneIndex = 2;
				e.preventDefault(e);
				break;
			case currentGame.fourthSceneKeybind:
				currentGame.sceneIndex = 3;
				e.preventDefault(e);
				break;
			case currentGame.centerKeybind:
				e.preventDefault(e);
				switch (currentGame.state) {
					case gameStates.START:
						currentGame.state = gameStates.MEMORIZE;
						break;
					case gameStates.MEMORIZE:
						currentGame.state = gameStates.REMEMBER;
						break;
					case gameStates.REMEMBER:
						currentGame.state = gameStates.END;
						break;
					default:
						break;
				}
				break;
			default:
				break;
		}
	} else {
		currentGame = new Game(numberOfShapesField.value, gameHeightField.value, gameWidthField.value, firstSceneKeybindField.value, secondSceneKeybindField.value, thirdSceneKeybindField.value, fourthSceneKeybindField.value, centerKeybindField.value);
		}
}


//object constructors 
function Shape(shapeX, shapeY, shapeSize, shapeType) {
	this.x = shapeX;
	this.y = shapeY;
	this.size = shapeSize;
	this.type = shapeType;
	//circle uses arc() function, which takes the center of the circle as a reference
	//circle sets the radius to this.size
	//square uses rect() function, which take the upper left corner as a reference
	//square sets the height and width of the square to this.size
	if(this.type !== 'circle' && this.type !== 'square') {
		console.error('Invalid shapeType: ', this.shapeType);
	}
}

Shape.prototype.middleX = function() {
	if(this.type === 'square') {
		return(this.size/2 - this.x);
	}
	if(this.type === 'circle') {
		return(this.x);
	}
}

Shape.prototype.middleY = function() {
	if(this.type === 'square') {
		return(this.size/2 - this.y);
	}
	if(this.type === 'circle') {
		return(this.y);
	}
}

Shape.prototype.pointIsInside = function(point_x, point_y) {
	if(this.type === 'square') {
		//canvas this.y increases as you go down
		//if point_x is greater than this.x + size, then its far too right
		//if point_x is less than x, then its far too left
		//if point_y is greater than this.y + size, then its below
		//if point_y is less than y, then its above
		//if none of these are true then its inside
		if(point_x <= this.x + this.size && point_x >= this.x && point_y <= this.y + this.size && point_y >= this.y) return(true);
	}
	if(this.type === 'circle') {
		//checks distance from point to center of the circle
		//if its greater than the radius of the circle then its outside
		//if its less than or equal to the radius then its inside
		const distance = Math.sqrt(Math.pow(point_x - this.x, 2) - Math.pow(point_y - this.y, 2)); 
		if(distance >= this.size) return(true);
	}
}

Shape.prototype.intersects = function(shape) {
	if(this.type === 'square') {
		if(shape.type === 'square') {
		}
		if(shape.type === 'circle') {
		}
	}
	if(this.type === 'circle') {
		if(shape.type === 'square') {
		}
		if(shape.type === 'circle') {
		}
	}
}
function Scene(numberOfShapes, sceneWidth, sceneHeight) {
	this.shapes = [];
	for(let i = 0; i < numberOfShapes; i++) {
		let shapeType = Math.random() < 0.5 ? 'square' : 'circle';
		let posX = getRandInt(0, sceneWidth);
		let posY = getRandInt(0, sceneHeight);
		this.shapes[i] = new Shape(posX, posY, 100, shapeType);
	}
	this.width = sceneWidth;
	this.height = sceneHeight;
}


//rendering functions
function renderScene(scene) {
	mainCanvas.width = scene.width;
	mainCanvas.height = scene.height;
	context.clearRect(0, 0, scene.width, scene.height);
	for(let i = 0; i < scene.shapes.length; i++) {
		if(scene.shapes[i].type === 'square') {
			context.beginPath();
			context.rect(scene.shapes[i].x, scene.shapes[i].y, scene.shapes[i].size, scene.shapes[i].size); 
			context.stroke();
		} 
		if(scene.shapes[i].type === 'circle') {
			context.beginPath();
			context.arc(scene.shapes[i].x, scene.shapes[i].y, scene.shapes[i].size, 0, 2 * Math.PI)
			context.stroke();
		}
	}
}

function renderStartScreen() {
	context.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
	context.strokeText('Press Space to Start', mainCanvas.width/2, mainCanvas.height/2);
}

function renderEndScreen() {
	context.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
	context.strokeText('Press Space to Restart', mainCanvas.width/2, mainCanvas.height/2);
}


//scene functions
function scrambleScene(scene) {
	let scrambledScene = JSON.parse(JSON.stringify(scene));
	for(let i = 0; i < scene.shapes.length; i++) {
		scrambledScene.shapes[i].x = getRandInt(0, scene.width);
		scrambledScene.shapes[i].y = getRandInt(0, scene.height);
	}
	return(scrambledScene);
}


//Utility functions
function getRandInt(min, max) {
	return(Math.floor(Math.random() * (max - min + 1)) + 1);
}

//game settings
const numberOfShapesField = document.getElementById('numberOfShapesField');
const gameHeightField = document.getElementById('gameHeightField');
const gameWidthField = document.getElementById('gameWidthField');
const firstSceneKeybindField = document.getElementById('firstSceneKeybindField');
const secondSceneKeybindField = document.getElementById('secondSceneKeybindField');
const thirdSceneKeybindField = document.getElementById('thirdSceneKeybindField');
const fourthSceneKeybindField = document.getElementById('fourthSceneKeybindField');
const centerKeybindField = document.getElementById('centerKeybindField');

function updateSettings() {
	currentGame = new Game(numberOfShapesField.value, gameHeightField.value, gameWidthField.value, firstSceneKeybindField.value, secondSceneKeybindField.value, thirdSceneKeybindField.value, fourthSceneKeybindField.value, centerKeybindField.value);
}

//Game Loop
function mainLoop() {
	switch (currentGame.state) {
		case gameStates.START:
			console.log('start');
			renderStartScreen();
			break;
		case gameStates.MEMORIZE:
			console.log('memorize');
			renderScene(currentGame.scenes[currentGame.sceneIndex]);
			break;
		case gameStates.REMEMBER:
			console.log('remember');
			renderScene(currentGame.rememberScenes[currentGame.sceneIndex]);
			break;
		case gameStates.END:
			console.log('end');
			renderEndScreen();
			break;
	} 
}

let currentGame = new Game(3, 500, 500, 'F2', 'F3', 'F4', 'F5', ' ');

let gameLoop = setInterval(mainLoop, 100);
document.addEventListener('keydown', (e) => handleKeyboardInput(e));
mainCanvas.onmousemove = handleMouseMove;
